package jvlite.core.listener;

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import jvlite.authority.AuthLoader;
import jvlite.core.JLiteContext;
import jvlite.core.PluginManger;
import jvlite.dao.createTable.AutoCreateTable;
import jvlite.ioc.BeanFactory;
import jvlite.ioc.BeanGenerater;
import jvlite.ioc.Injector;
import jvlite.mvc.ActionLoader;
import jvlite.plugin.IPlugin;
import jvlite.util.LogUtil;

public class JliteListener implements ServletContextListener{
	
	private static ThreadPoolExecutor  mExecutor = (ThreadPoolExecutor)Executors.newFixedThreadPool(6);

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		mExecutor.shutdown();
		LogUtil.info("Jlite was destroyed...");
	}

	@Override
	public void contextInitialized(ServletContextEvent svltContxt) {
		//context
		JLiteContext.context = svltContxt;
		//bean factory
		BeanFactory.init();
		//start necessary modules 
		Future<Boolean> future1 = mExecutor.submit(new BeanGenerater());
		Future<Boolean> future2 = mExecutor.submit(new ActionLoader());
		do {
			LogUtil.info("futureTasks: 1->"+future1.isDone()+",2->"+future2.isDone());
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (mExecutor.getCompletedTaskCount() < 2);
		// load the custom configurations from JliteApp
		Future<Boolean> future3 = null;
		if (JLiteContext.isInjector) {
			future3 = mExecutor.submit(new Injector());
//			moduleCount++;
			do {
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} while (!future3.isDone());
		}
		Integer moduleCount = new Integer(3);
		// continue the tasks
		Future<Boolean> future4 = null;
		if (JLiteContext.isAuthority) {
			future4 = mExecutor.submit(new AuthLoader());
			moduleCount++;
		}
		Future<Boolean> future5 = null;
		if (JLiteContext.isPlugin) {
			future5 = mExecutor.submit(new Callable<Boolean>() {
				@Override
				public Boolean call() throws Exception {
					for (IPlugin plugin : PluginManger.pluginSet) {
						plugin.initialize();
						plugin.install();
					}
					return true;
				}
			});
			moduleCount++;
		}
		//the second round to initialize framework
		Future<Boolean> future6 = null;
		if (JLiteContext.isGenerateTable) {
			future6 = mExecutor.submit(new Callable<Boolean>() {
				@Override
				public Boolean call() throws Exception {
					AutoCreateTable.generateTable(null);
					return true;
				}
			});
			moduleCount++;
		}
		do {
			LogUtil.info("futureTasks: 3->"+future3+",4->"+future4+",5->"+future5+",6->"+future6);
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (mExecutor.getCompletedTaskCount() < moduleCount);
		LogUtil.info("futureTasks: 1->"+future1.isDone()+",2->"+future2.isDone());
		LogUtil.info("futureTasks: 3->"+future3+",4->"+future4+",5->"+future5+",6->"+future6);
		LogUtil.info("JLite has been Started");
	}
	
}